package org.jetlinks.community.mstn.service;

import lombok.AllArgsConstructor;
import org.jetlinks.community.auth.service.UserDetailService;
import org.jetlinks.community.auth.service.request.SaveUserRequest;
import org.jetlinks.community.dashboard.DashboardManager;
import org.jetlinks.community.dashboard.MeasurementParameter;
import org.jetlinks.community.dashboard.SimpleMeasurementValue;
import org.jetlinks.community.dashboard.web.request.DashboardMeasurementRequest;
import org.jetlinks.community.device.entity.DeviceProperty;
import org.jetlinks.community.mstn.entity.vo.DeviceValueResVO;
import org.jetlinks.community.mstn.entity.vo.UserCreateReqVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class MstnSystemService {

    private final UserDetailService userDetailService;

    private final DashboardManager dashboardManager;

    /**
     * 保存用户,自动关联角色{@link SaveUserRequest#getRoleIdList()}以及机构(部门){@link SaveUserRequest#getOrgIdList()}
     *
     * @param createReqVO 保存请求
     * @return 用户ID
     */
    @Transactional
    public Mono<String> createUser(UserCreateReqVO createReqVO, String tenantId) {
        SaveUserRequest request = createReqVO.getSaveUserRequest(tenantId);
        return userDetailService.saveTenantUser(request,tenantId,true);
    }

    //用户详情
    public Mono<UserCreateReqVO> getUserDetail(String userId) {
        return userDetailService.findUserDetail(userId)
           .map(UserCreateReqVO::of);
    }


    /**
     * 初始化查询对象
     * @return
     */
    public DashboardMeasurementRequest initRequest (String deviceId , String productId ,List<String> valueNameList){
        DashboardMeasurementRequest request = new DashboardMeasurementRequest();
        request.setDashboard("device");
        request.setObject(productId);
        request.setDimension("history");
        request.setMeasurement("properties");
        Map<String, Object> params = new LinkedHashMap<>();
        params.put("deviceId",deviceId);
        params.put("history", 1);
        params.put("properties", valueNameList);
        request.setParams(params);
        return request;
    }

    /**
     * 获取所有的值
     * @param requests
     * @return
     */
    public Flux<DeviceProperty> getDeviceProperty(Flux<DashboardMeasurementRequest> requests) {
        return requests.flatMap(request -> dashboardManager
                .getDashboard(request.getDashboard())
                .flatMap(dash -> dash.getObject(request.getObject()))
                .flatMap(obj -> obj.getMeasurement(request.getMeasurement()))
                .flatMap(meas -> meas.getDimension(request.getDimension()))
                .filter(dim -> !dim.isRealTime()) //实时数据请使用EventSource方式
                .flatMapMany(dim -> {
                    Flux<SimpleMeasurementValue> object = (Flux<SimpleMeasurementValue>) dim.getValue(MeasurementParameter.of(request.getParams()));
                    return object.switchIfEmpty(emptyValue(request));
                })
                .map(val -> {
                    return((DeviceProperty) val.getValue());
                }));
    }

    //返回空值
    private Flux<SimpleMeasurementValue> emptyValue(DashboardMeasurementRequest request) {
        List<String> properties = (List<String>)request.getParams().get("properties");
        return Flux.fromIterable(properties.stream().map(s -> {
            DeviceProperty deviceProperty = new DeviceProperty();
            deviceProperty.setDeviceId(request.getParams().get("deviceId").toString());
            deviceProperty.setValue(0);
            deviceProperty.setCreateTime(0L);
            deviceProperty.setPropertyName(s);
            return SimpleMeasurementValue.of( deviceProperty,0L);
        }).collect(Collectors.toList()));
    }

}
